import 'dart:async';

import 'package:get/get.dart';
import 'package:largefriends/entity/entities/lf_relation_result_entity.dart';
import 'package:swipable_stack/swipable_stack.dart';

import '../../entity/entities/lf_user_entity.dart';
import '../../events/change_filter_event.dart';
import '../../events/payment_success_event.dart';
import '../../events/user_change_event.dart';
import '../../events/user_relation_event.dart';
import '../../service/manager/lf_event_helper.dart';
import '../../net/error_handle.dart';
import '../../net/lf_api_url.dart';
import '../../net/lf_dio_util.dart';
import '../../service/lf_auth_service.dart';
import '../../utils/lf_dialog_utils.dart';
import '../lf_base_controller.dart';
import '../../service/manager/lf_search_filter_helper.dart';

class LfTabSparkLogic extends GetxController {
  final SwipableStackController controller = SwipableStackController();

  StreamSubscription? streamSubscriptionUserAction;
  StreamSubscription? streamSubscriptionUserInfo;
  StreamSubscription? streamSubscriptionChangeFilter,
      streamSubscriptionPaymentSuccess;
  RxBool showRemind = false.obs;
  List<LfUserEntity> dataList = List.empty(growable: true);
  LfAuthService authService = Get.find();
  bool showSparkLimit = false;

  @override
  void onReady() {
    super.onReady();
    streamSubscriptionUserInfo =
        LfEventHelper().getEvent().on<UserChangeEvent>().listen((event) {
      ///TODO
      update();
    });

    streamSubscriptionChangeFilter =
        LfEventHelper().getEvent().on<ChangeFilterEvent>().listen((event) {
      if (showSparkLimit == false) {
        request();
      }
    });

    streamSubscriptionUserAction = LfEventHelper()
        .getEvent()
        .on<UserRelationEvent>()
        .listen((UserRelationEvent event) {
      if (event.type == UserRelationType.block) {
        dataList.removeWhere((element) => element.userId == event.uid);
        update();
      } else if (event.type == UserRelationType.wink) {
        for (var element in dataList) {
          if (element.userId == event.uid) {
            element.winked = 1;
            update();
          }
        }
      } else if (event.type == UserRelationType.like) {
        if (event.fromSpark == true) {
          return;
        }
        dataList.removeWhere((element) => element.userId == event.uid);
        update();
      }
    });
    streamSubscriptionPaymentSuccess =
        LfEventHelper().getEvent().on<PaymentSuccessEvent>().listen((event) {
      if (showSparkLimit) {
        showSparkLimit = false;
        request();
      }
    });
    request();
  }

  LoadingState state = LoadingState.init;

  void request() async {
    if (authService.currentAccount!.isGold()) {
      _getUsers();
    } else {
      if (authService.limitEntity == null) {
        state = LoadingState.loading;
        if (dataList.isEmpty) {
          update();
        }
        await authService.refreshConfig();
      }
      if (authService.limitEntity == null) {
        state = LoadingState.failed;
        if (dataList.isEmpty) {
          update();
        }
      } else {
        if (authService.canSpark()) {
          _getUsers();
        } else {
          showSparkLimit = true;
          update();
        }
      }
    }
  }

  void _getUsers() async {
    state = LoadingState.loading;
    controller.currentIndex = 0;
    dataList.clear();
    update();

    Map<String, dynamic> requestMap = {};
    requestMap.addAll(LfSearchFilterHelper().getSearchFilter().getSearchMap());
    requestMap.putIfAbsent("find[photo]", () => 1);
    requestMap.putIfAbsent('offset', () => 20);
    // requestMap.putIfAbsent('type', () => 'spark');
    requestMap.putIfAbsent('refresh', () => 1);

    LfDio.instance
        .get<List<LfUserEntity>>(url: apiSearch, params: requestMap)
        .then((value) {
      dataList.clear();
      if (value.isEmpty) {
        state = LoadingState.empty;
        update();
        return;
      }
      dataList.addAll(value);
      state = LoadingState.success;
      controller.currentIndex = 0;
      update();
    }, onError: (error) {
      if (error is NetError) {
        showSnackBar(error.msg);
      }
      state = LoadingState.failed;
      controller.currentIndex = 0;
      update();
    });
  }

  void like(LfUserEntity user) {
    LfDio.instance.post<LfRelationResultEntity>(
      url: apiLikeUser,
      params: {'userId': user.userId, 'from': 'spark'},
    ).then((value) {
      authService.currentSparkCnt = value.sparkCntToday;
      authService.currentLikeCnt = value.likedCntToday;
      LfEventHelper().getEvent().fire(UserRelationEvent(
          uid: user.userId!,
          type: UserRelationType.like,
          userEntity: user,
          fromSpark: true));
    }, onError: (error) {
      if (error is NetError) {
        showSnackBar(error.msg);
        if (error.code == 30004016) {
          // _sparkLimit();TODO
        }
      }
    });
    showRemind.value = false;
  }

  void pass(LfUserEntity user) {
    LfDio.instance.post<LfRelationResultEntity>(
      url: apiUnLikeUser,
      params: {'userId': user.userId, 'from': 'spark'},
    ).then((value) {
      authService.currentSparkCnt = value.sparkCntToday;
      authService.currentLikeCnt = value.likedCntToday;
      LfEventHelper().getEvent().fire(UserRelationEvent(
          uid: user.userId!,
          type: UserRelationType.unlike,
          userEntity: user,
          fromSpark: true));
    }, onError: (error) {
      if (error is NetError) {
        showSnackBar(error.msg);
        if (error.code == 30004016) {
          // _sparkLimit();TODO
        }
      }
    });
    showRemind.value = true;
  }
}
